package com.banhujiu.lakalaPlugin.entities;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import com.banhujiu.lakalaPlugin.utils.StringUtils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author 刘博文
 * @date 2017/4/6 0006 18:26
 */
public class LklNotifyEntity {

	private HashMap<String, String> map = new HashMap<String, String>() {
		private static final long serialVersionUID = -5625866124011093551L;

		{
			put("mch_id", "MchId");
			put("device_info", "DeviceInfo");
			put("nonce_str", "NonceStr");
			put("sign", "Sign");
			put("result_code", "ResultCode");
			put("err_code", "ErrCode");
			put("err_code_des", "ErrCodeDes");
			put("openid", "Openid");
			put("trade_type", "TradeType");
			put("total_fee", "TotalFee");
			put("transaction_id", "TransactionId");
			put("out_trade_no", "OutTradeNo");
			put("attach", "Attach");
			put("time_end", "TimeEnd");
			put("Pay_type", "PayType");
			put("card_no", "CardNo");
			put("pay_amt", "PayAmt");
			put("batchbillno", "Batchbillno");
			put("systraceno", "Systraceno");
			put("orderid_scan", "OrderidScan");
			put("refernumber", "Refernumber");
			put("bank_type", "BankType");
			put("fee_type", "FeeType");
			put("cash_fee", "CashFee");
			put("cash_fee_type", "CashFeeType");
			put("coupon_fee", "CouponFee");
			put("coupon_count", "CouponCount");
			put("coupon_id_$n", "CouponId$n");
			put("coupon_fee_$n", "CouponFee$n");
			put("is_subscribe", "IsSubscribe");
		}
	};

	private LinkedHashMap<String, String> dataMap = new LinkedHashMap<>();

	private String data;
	/**
	 * 商户号
	 */
	private String mchId;

	/**
	 * 设备号
	 */
	private String deviceInfo;

	/**
	 * 随机字符串
	 */
	private String nonceStr;

	/**
	 * 签名
	 */
	private String sign;

	/**
	 * 业务结果
	 */
	private String resultCode;

	/**
	 * 错误代码
	 */
	private String errCode;

	/**
	 * 错误代码描述
	 */
	private String errCodeDes;

	/**
	 * 用户标识
	 */
	private String openid;

	/**
	 * 交易类型
	 */
	private String tradeType;

	/**
	 * 总金额
	 */
	private String totalFee;

	/**
	 * 商户支付订单号
	 */
	private String transactionId;

	/**
	 * 商户订单号
	 */
	private String outTradeNo;

	/**
	 * 商家数据包
	 */
	private String attach;

	/**
	 * 支付完成时间
	 */
	private String timeEnd;

	/**
	 * 支付方式
	 */
	private String PayType;

	/**
	 * 交易卡号
	 */
	private String cardNo;

	/**
	 * 支付金额
	 */
	private String payAmt;

	/**
	 * 批次号
	 */
	private String batchbillno;

	/**
	 * 凭证号
	 */
	private String systraceno;

	/**
	 * 扫码订单号
	 */
	private String orderidScan;

	/**
	 * 系统参考号
	 */
	private String refernumber;

	/**
	 * 付款银行
	 */
	private String bankType;

	/**
	 * 货币种类
	 */
	private String feeType;

	/**
	 * 现金支付金额
	 */
	private String cashFee;

	/**
	 * 现金支付货币类型
	 */
	private String cashFeeType;

	/**
	 * 代金券或立减优惠金额
	 */
	private String couponFee;

	/**
	 * 代金券或立减优惠使用数量
	 */
	private String couponCount;

	/**
	 * 代金券或立减优惠ID
	 */
	private String couponId$n;

	/**
	 * 单个代金券或立减优惠支付金额
	 */
	private String couponFee$n;

	/**
	 * 是否关注公众账号
	 */
	private String isSubscribe;

	public static LklNotifyEntity getEntity(String sourceString, String sign) {
		LinkedHashMap<String, String> data = new LinkedHashMap<>();
		JsonObject jsonObject = new JsonParser().parse(sourceString).getAsJsonObject();
		for (Map.Entry<String, JsonElement> stringObjectEntry : jsonObject.entrySet()) {
			String key = stringObjectEntry.getKey();
			String value = StringUtils.valueOf(stringObjectEntry.getValue());
			data.put(key, value);
		}
		data.put("sign", sign);
		return LklNotifyEntity.getEntity(data, sourceString);
	}

	private static LklNotifyEntity getEntity(LinkedHashMap<String, String> result, String sourceRequest) {
		if (result == null) {
			return null;
		}
		LklNotifyEntity notifyEntity = new LklNotifyEntity();
		notifyEntity.setDataMap(result);
		notifyEntity.setData(sourceRequest);
		Class<?> clazz = notifyEntity.getClass();
		for (Map.Entry<String, String> entry : result.entrySet()) {
			String variable = notifyEntity.map.get(entry.getKey());
			if (variable == null) {
				continue;
			}
			String methodName = "set" + variable;
			try {
				Method method = clazz.getMethod(methodName, String.class);
				method.invoke(notifyEntity, entry.getValue());
			} catch (Exception e) {
				throw new RuntimeException("变量" + entry.getKey() + "反射执行set方法失败，值为" + entry.getValue());
			}
		}
		return notifyEntity;
	}


	public String getData() {
		return data;
	}

	public void setData(String data) {
		this.data = data;
	}

	public LinkedHashMap<String, String> getDataMap() {
		return dataMap;
	}

	public void setDataMap(LinkedHashMap<String, String> dataMap) {
		this.dataMap = dataMap;
	}

	public String getMchId() {
		return mchId;
	}

	public void setMchId(String mchId) {
		this.mchId = mchId;
	}

	public String getDeviceInfo() {
		return deviceInfo;
	}

	public void setDeviceInfo(String deviceInfo) {
		this.deviceInfo = deviceInfo;
	}

	public String getNonceStr() {
		return nonceStr;
	}

	public void setNonceStr(String nonceStr) {
		this.nonceStr = nonceStr;
	}

	public String getSign() {
		return sign;
	}

	public void setSign(String sign) {
		this.sign = sign;
	}

	public String getResultCode() {
		return resultCode;
	}

	public void setResultCode(String resultCode) {
		this.resultCode = resultCode;
	}

	public String getErrCode() {
		return errCode;
	}

	public void setErrCode(String errCode) {
		this.errCode = errCode;
	}

	public String getErrCodeDes() {
		return errCodeDes;
	}

	public void setErrCodeDes(String errCodeDes) {
		this.errCodeDes = errCodeDes;
	}

	public String getOpenid() {
		return openid;
	}

	public void setOpenid(String openid) {
		this.openid = openid;
	}

	public String getTradeType() {
		return tradeType;
	}

	public void setTradeType(String tradeType) {
		this.tradeType = tradeType;
	}

	public String getTotalFee() {
		return totalFee;
	}

	public void setTotalFee(String totalFee) {
		this.totalFee = totalFee;
	}

	public String getTransactionId() {
		return transactionId;
	}

	public void setTransactionId(String transactionId) {
		this.transactionId = transactionId;
	}

	public String getOutTradeNo() {
		return outTradeNo;
	}

	public void setOutTradeNo(String outTradeNo) {
		this.outTradeNo = outTradeNo;
	}

	public String getAttach() {
		return attach;
	}

	public void setAttach(String attach) {
		this.attach = attach;
	}

	public String getTimeEnd() {
		return timeEnd;
	}

	public void setTimeEnd(String timeEnd) {
		this.timeEnd = timeEnd;
	}

	public String getPayType() {
		return PayType;
	}

	public void setPayType(String payType) {
		PayType = payType;
	}

	public String getCardNo() {
		return cardNo;
	}

	public void setCardNo(String cardNo) {
		this.cardNo = cardNo;
	}

	public String getPayAmt() {
		return payAmt;
	}

	public void setPayAmt(String payAmt) {
		this.payAmt = payAmt;
	}

	public String getBatchbillno() {
		return batchbillno;
	}

	public void setBatchbillno(String batchbillno) {
		this.batchbillno = batchbillno;
	}

	public String getSystraceno() {
		return systraceno;
	}

	public void setSystraceno(String systraceno) {
		this.systraceno = systraceno;
	}

	public String getOrderidScan() {
		return orderidScan;
	}

	public void setOrderidScan(String orderidScan) {
		this.orderidScan = orderidScan;
	}

	public String getRefernumber() {
		return refernumber;
	}

	public void setRefernumber(String refernumber) {
		this.refernumber = refernumber;
	}

	public String getBankType() {
		return bankType;
	}

	public void setBankType(String bankType) {
		this.bankType = bankType;
	}

	public String getFeeType() {
		return feeType;
	}

	public void setFeeType(String feeType) {
		this.feeType = feeType;
	}

	public String getCashFee() {
		return cashFee;
	}

	public void setCashFee(String cashFee) {
		this.cashFee = cashFee;
	}

	public String getCashFeeType() {
		return cashFeeType;
	}

	public void setCashFeeType(String cashFeeType) {
		this.cashFeeType = cashFeeType;
	}

	public String getCouponFee() {
		return couponFee;
	}

	public void setCouponFee(String couponFee) {
		this.couponFee = couponFee;
	}

	public String getCouponCount() {
		return couponCount;
	}

	public void setCouponCount(String couponCount) {
		this.couponCount = couponCount;
	}

	public String getCouponId$n() {
		return couponId$n;
	}

	public void setCouponId$n(String couponId$n) {
		this.couponId$n = couponId$n;
	}

	public String getCouponFee$n() {
		return couponFee$n;
	}

	public void setCouponFee$n(String couponFee$n) {
		this.couponFee$n = couponFee$n;
	}

	public String getIsSubscribe() {
		return isSubscribe;
	}

	public void setIsSubscribe(String isSubscribe) {
		this.isSubscribe = isSubscribe;
	}

	@Override
	public String toString() {
		return "LklNotifyEntity{" +
				"mchId='" + mchId + '\'' +
				", deviceInfo='" + deviceInfo + '\'' +
				", nonceStr='" + nonceStr + '\'' +
				", sign='" + sign + '\'' +
				", resultCode='" + resultCode + '\'' +
				", errCode='" + errCode + '\'' +
				", errCodeDes='" + errCodeDes + '\'' +
				", openid='" + openid + '\'' +
				", tradeType='" + tradeType + '\'' +
				", totalFee='" + totalFee + '\'' +
				", transactionId='" + transactionId + '\'' +
				", outTradeNo='" + outTradeNo + '\'' +
				", attach='" + attach + '\'' +
				", timeEnd='" + timeEnd + '\'' +
				", PayType='" + PayType + '\'' +
				", cardNo='" + cardNo + '\'' +
				", payAmt='" + payAmt + '\'' +
				", batchbillno='" + batchbillno + '\'' +
				", systraceno='" + systraceno + '\'' +
				", orderidScan='" + orderidScan + '\'' +
				", refernumber='" + refernumber + '\'' +
				", bankType='" + bankType + '\'' +
				", feeType='" + feeType + '\'' +
				", cashFee='" + cashFee + '\'' +
				", cashFeeType='" + cashFeeType + '\'' +
				", couponFee='" + couponFee + '\'' +
				", couponCount='" + couponCount + '\'' +
				", couponId$n='" + couponId$n + '\'' +
				", couponFee$n='" + couponFee$n + '\'' +
				", isSubscribe='" + isSubscribe + '\'' +
				'}';
	}
}
